﻿using System.Xml;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using SdmxMl.Common;

namespace SdmxMl.Structure
{
    /// <summary>
    /// ConceptSchemeType describes the structure of a ConceptScheme element, which is 
    /// the preferred form (as of version 2.0) of presenting the concepts used in other 
    /// SDMX constructs. ConceptSchemes may be included inline (that is, with all details 
    /// provided in the instance or may be referenced externally. It is possible to use the 
    /// uri field to point to the location of an SDMX-ML Structure message which contains a 
    /// more detailed version of the concept. (This is termed an "external reference".) 
    /// If an external reference is being made, the isExternalReference attribute must be 
    /// set to "true". A Name may be provided as a child element (in multiple parallel 
    /// language versions) and an ID and version and agency information may be provided. 
    /// ConceptSchemes represent a collection of concepts which are used to describe a 
    /// meaningful set of distinct concepts, to be used in the reporting of data or metadata. 
    /// The validFrom and validTo attributes provide inclusive dates for providing supplemental 
    /// validity information about the version.
    /// </summary>
    public class ConceptSchemeType : Artefact
    {
        public static string GlobalIdBase = "GlobalConcepts_";

        #region Properties

        public override ArtefactRefTypedList ArtefactRefList
        {
            get
            {
                ArtefactRefTypedList list = new ArtefactRefTypedList();

                // Concept can refers codelists in Corerepresentation
                foreach (ConceptType c in ConceptList)
                {
                    if (c.CoreRepresentation.IsFilled)
                    {
                        ArtefactRefTyped at = new ArtefactRefTyped(
                           SdmxMl.Manager.SdmxArtefactType.CodeLists,
                           c.CoreRepresentation.Id, c.CoreRepresentation.AgencyId, c.CoreRepresentation.Version);
                        if (list.Contains(at.Type, at.FullIdent) == false)
                            list.Add(at);
                    }
                }

                return list;
            }
        }


        private ConceptList _conceptList;
        public ConceptList ConceptList
        {
            get { return _conceptList; }
            set { _conceptList = value; }
        }

        #endregion //Properties

        #region Constructors

        public ConceptSchemeType()
            : base()
        {
            Init();
        }

        private void Init()
        {
            _conceptList = new ConceptList();
        }


        public ConceptSchemeType(XmlNode nodeArtefact, SdmxNamespaceManager nsmgr) 
            : base(nodeArtefact, nsmgr)
        {
            Init();
            _conceptList.ReadXml(nodeArtefact, nsmgr, "./structure:Concept");
        }

        #endregion //Constructors

        #region Global Concepts (sdmx 1.0)

        // Translate Global concepts as a conceptScheme
        public void FillFromGlobalConcepts(List<XmlNode> ndList, SdmxNamespaceManager nsmgr)
        {
            _conceptList.ReadXml(ndList[0].ParentNode, nsmgr, "./structure:Concept");
            // Set Attribute of scheme from 1st concept
            if (_conceptList.Count > 0)
            {
                ConceptType c = _conceptList[0] as ConceptType;
                if (c != null)
                {
                    this.AgencyId = c.GlobalAgencyId;
                    this.version = c.GlobalVersion;
                    this.Id = GlobalIdBase + AgencyId;
                    // Put a explanation name in all languages
                    string info = "Simulated ConceptScheme from Global Concepts of " + AgencyId;
                    foreach (string lg in LangSupport.SupportedLanguages)
                        this.Name.TextList.Add(new TextType(lg, info));
                }
            }
        }

        #endregion //Global Concepts (sdmx 1.0)

        #region Override

        public override void WriteXmlInsider(XmlTextWriter xw)
        {
            string prefix = "structure";
            foreach (ConceptType c in _conceptList)
                c.WriteXml(xw, prefix, "Concept");
        }

        #endregion //Override

        #region Tree

        public override TreeNode FillNode(TreeNode parentNode)
        {
            TreeNode t = base.FillNode(parentNode);
            TreeNode tc = new TreeNode(_conceptList.ToString(), 1, 1);
            tc.Tag = _conceptList;
            t.Nodes.Add(tc);
            _conceptList.FillTree(tc);
            return t;
        }

        #endregion //Tree

        #region Artefact Type

        public override Manager.SdmxArtefactType ArType
        {
            get { return Manager.SdmxArtefactType.Concepts; }
        }

        #endregion

    }
}
